#pragma once
#include <iostream>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <string.h>


const std::string gshmpath = "/home/qiangsir/linux/system/shm";
const int gproid = 0x666;
const int gsize = 4096;
mode_t gmode = 0666;

std::string ToHex(key_t key)
{
    char buffer[gsize];
    snprintf(buffer, sizeof(buffer), "0x%x", key);
    return buffer;
}

class Shm
{
private:
    void CreatShmhelper(int shmflg)
    {
        // 创建共享密匙key
        _key = ftok(gshmpath.c_str(), gproid);
        if (_key < 0)
        {
            std::cerr << "ftok error";
            return;
        }
        std::cout << ToHex(_key) << std::endl;

        // 开辟共享内存
        _shmid = ::shmget(_key, gsize, shmflg);
        if (_shmid < 0)
        {
            std::cerr << "shmget error";
            return;
        }
    }

public:
    Shm() : _shmid(-1), _key(0), _addr(nullptr)
    {
    }
    ~Shm()
    {
    }
    void CreatShm()
    {
        if (_shmid == -1)
            CreatShmhelper(IPC_CREAT | IPC_EXCL | gmode);
    }
    void GetShm()
    {
        CreatShmhelper(IPC_CREAT);
    }

    // 挂接
    void Shmattch()
    {
        _addr = ::shmat(_shmid, nullptr, 0);
        if ((long long)_addr == -1)
        {
            std::cerr << "shmat error" << std::endl;
            return;
        }
    }
    // 去关联
    void Shmdeattch()
    {
        if (_addr != nullptr)
            ::shmdt(_addr);
        std::cout << "deattch done" << std::endl;
    }
    // 删除共享内存
    void Shmdelete()
    {
        ::shmctl(_shmid, IPC_RMID, nullptr);
    }
    // 获取地址
    void *Getaddr()
    {
        return _addr;
    }

private:
    key_t _key;
    int _shmid;
    void *_addr;
};

// 临时创建
Shm shm;

struct Data
{
    char status[32];
    char lasttime[48];
    char image[4000];
};